package com.scpii.universal.service.impl;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;

public class HttpClientExecutor
{		
	protected static final int DEFAULT_MAX_CONNECTIONS = 5;	// 缺省读取时间
	protected static final int DEFAULT_READ_TIMEOUT = 5000;
	
	private ClientConnectionManager		connectionManager;
	private HttpClient					httpClient;
	private HttpParams					httpParams;

	/************ Singleton ***********/
	private static HttpClientExecutor	instance				= new HttpClientExecutor();

	private HttpClientExecutor()
	{
		// 初始化 SchemeRegistry
		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

		// 初始化 HttpParams
		httpParams = new BasicHttpParams();
		HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);		
		ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);
		ConnManagerParams.setTimeout(httpParams, DEFAULT_READ_TIMEOUT);
		// 创建线程安全的 ClientConnectionManager
		connectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
		// 创建 HttpClient
		httpClient = new DefaultHttpClient(connectionManager, httpParams);
	}

	public static HttpClientExecutor getInstance()
	{
		return instance;
	}

	/************ Singleton ***********/

	public void shutdown()
	{
		connectionManager.shutdown();
	}
	
	
	
	/**
	 * 创建自适应网络的 HttpPost
	 */
	private HttpPost newHttpPost(String destUrl) throws Exception
	{
		HttpPost httpPost = new HttpPost(destUrl);
		httpPost.setHeader("accept", "*/*");		
	
		return httpPost;
	}


	/**
	 * 创建自适应网络的 HttpGet
	 */
	private HttpGet newHttpGet(String destUrl) throws Exception
	{
		HttpGet httpGet = new HttpGet(destUrl);
		httpGet.setHeader("accept", "*/*");	
		
		
		return httpGet;
	}

	/**
	 * 执行 POST 请求，POST 请求的服务器响应
	 */	
	public byte[] executePost(String url, byte[] entity)
	{
		byte[] resData = null;
		HttpPost httpPost = null;
		try
		{		
			
			httpPost = this.newHttpPost(url);

			// 设置 post 参数
			if (entity != null && entity.length > 0)
			{			
				httpPost.setEntity(new ByteArrayEntity(entity));
			}
			
			// 发送请求
			HttpResponse httpResponse = httpClient.execute(httpPost);
			// 处理返回消息
			StatusLine statusLine = null;
			if (httpResponse == null || (statusLine = httpResponse.getStatusLine()) == null)
				return null;

			int responseCode = statusLine.getStatusCode();			

			if (responseCode == HttpStatus.SC_OK)
			{
				resData = EntityUtils.toByteArray(httpResponse.getEntity());
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			if (httpPost != null)
			{
				httpPost.abort();
			}			
		}
		return resData;
	}

	/**
	 * 执行 GET 请求，GET 请求的服务器响应为指定资源类型
	 */	
	public byte[] executeGet(String url)
	{
		byte[] resData = null;
		HttpGet httpGet = null;
		try
		{
						
			httpGet = this.newHttpGet(url);
			// 发送请求
			HttpResponse httpResponse = httpClient.execute(httpGet);

			// 处理返回消息			
			StatusLine statusLine = null;
			if (httpResponse == null || (statusLine = httpResponse.getStatusLine()) == null)
				return null;

			int responseCode = statusLine.getStatusCode();			

			if (responseCode == HttpStatus.SC_OK)
			{
				resData = EntityUtils.toByteArray(httpResponse.getEntity());
			}
						
		}
		catch (Exception e)
		{			
			e.printStackTrace();
			if (httpGet != null)
			{
				httpGet.abort();
			}				

		}
		return resData;
	}
	
}
